home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Modules / termios.c < prev    next >
Text File  |  1995-12-21  |  6KB  |  244 lines

  1. /* termiosmodule.c -- POSIX terminal I/O module implementation.  */
  2.  
  3. #include <Python.h>
  4.  
  5. #define PyInit_termios inittermios
  6.  
  7. #include <termios.h>
  8.  
  9. #define BAD "bad termios argument"
  10.  
  11. static PyObject *TermiosError;
  12.  
  13. /* termios = tcgetattr(fd)
  14.    termios is
  15.    [iflag, oflag, cflag, lflag, ispeed, ospeed, [cc[0], ..., cc[NCCS]]] 
  16.  
  17.    Return the attributes of the terminal device.  */
  18.  
  19. static PyObject *
  20. termios_tcgetattr(self, args)
  21.     PyObject *self;
  22.     PyObject *args;
  23. {
  24.     int fd;
  25.     struct termios mode;
  26.     PyObject *cc;
  27.     speed_t ispeed, ospeed;
  28.     PyObject *v;
  29.     int i;
  30.     char ch;
  31.  
  32.     if (!PyArg_Parse(args, "i", &fd))
  33.         return NULL;
  34.  
  35.     if (tcgetattr(fd, &mode) == -1)
  36.         PyErr_SetFromErrno(TermiosError);
  37.  
  38.     ispeed = cfgetispeed(&mode);
  39.     ospeed = cfgetospeed(&mode);
  40.  
  41.     cc = PyList_New(NCCS);
  42.     if (cc == NULL)
  43.         return NULL;
  44.     for (i = 0; i < NCCS; i++) {
  45.         ch = (char)mode.c_cc[i];
  46.         v = PyString_FromStringAndSize(&ch, 1);
  47.         if (v == NULL)
  48.             return NULL;
  49.         PyList_SetItem(cc, i, v);
  50.     }
  51.  
  52.     /* Convert the MIN and TIME slots to integer.  On some systems, the
  53.        MIN and TIME slots are the same as the EOF and EOL slots.  So we
  54.        only do this in noncanonical input mode.  */
  55.     if (mode.c_lflag & ICANON == 0) {
  56.         v = PyInt_FromLong((long)mode.c_cc[VMIN]);
  57.         if (v == NULL)
  58.             return NULL;
  59.         PyList_SetItem(cc, VMIN, v);
  60.         v = PyInt_FromLong((long)mode.c_cc[VTIME]);
  61.         if (v == NULL)
  62.             return NULL;
  63.         PyList_SetItem(cc, VTIME, v);
  64.     }
  65.  
  66.     v = PyList_New(7);
  67.     PyList_SetItem(v, 0, PyInt_FromLong((long)mode.c_iflag));
  68.     PyList_SetItem(v, 1, PyInt_FromLong((long)mode.c_oflag));
  69.     PyList_SetItem(v, 2, PyInt_FromLong((long)mode.c_cflag));
  70.     PyList_SetItem(v, 3, PyInt_FromLong((long)mode.c_lflag));
  71.     PyList_SetItem(v, 4, PyInt_FromLong((long)ispeed));
  72.     PyList_SetItem(v, 5, PyInt_FromLong((long)ospeed));
  73.     PyList_SetItem(v, 6, cc);
  74.  
  75.     return v;
  76. }
  77.  
  78. /* tcsetattr(fd, when, termios)
  79.    Set the attributes of the terminal device.  */
  80.  
  81. static PyObject *
  82. termios_tcsetattr(self, args)
  83.     PyObject *self;
  84.     PyObject *args;
  85. {
  86.     int fd, when;
  87.     struct termios mode;
  88.     speed_t ispeed, ospeed;
  89.     PyObject *term, *cc, *v;
  90.     int i;
  91.  
  92.     if (!PyArg_Parse(args, "(iiO)", &fd, &when, &term))
  93.         return NULL;
  94.     if (!PyList_Check(term) || PyList_Size(term) != 7) {
  95.         PyErr_SetString(PyExc_TypeError, BAD);
  96.         return NULL;
  97.     }
  98.     for (i = 0; i < 6; i++)
  99.         if (!PyInt_Check(PyList_GetItem(term, i))) {
  100.             PyErr_SetString(PyExc_TypeError, BAD);
  101.             return NULL;
  102.         }
  103.  
  104.     mode.c_iflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 0));
  105.     mode.c_oflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 1));
  106.     mode.c_cflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 2));
  107.     mode.c_lflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 3));
  108.     ispeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 4));
  109.     ospeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 5));
  110.     cc = PyList_GetItem(term, 6);
  111.  
  112.     if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
  113.         PyErr_SetString(PyExc_TypeError, BAD);
  114.         return NULL;
  115.     }
  116.  
  117.     for (i = 0; i < NCCS; i++) {
  118.         v = PyList_GetItem(cc, i);
  119.         if (PyString_Check(v) && PyString_Size(v) == 1)
  120.             mode.c_cc[i] = (cc_t) * PyString_AsString(v);
  121.         else if (PyInt_Check(v))
  122.             mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
  123.         else {
  124.             PyErr_SetString(PyExc_TypeError, BAD);
  125.             return NULL;
  126.         }
  127.     }
  128.  
  129.     if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
  130.         PyErr_SetFromErrno(TermiosError);
  131.     if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
  132.         PyErr_SetFromErrno(TermiosError);
  133.     if (tcsetattr(fd, when, &mode) == -1)
  134.         PyErr_SetFromErrno(TermiosError);
  135.  
  136.     Py_INCREF(Py_None);
  137.     return Py_None;
  138. }
  139.  
  140. /* tcsendbreak(fd, duration)
  141.    Generate a break condition.  */
  142.  
  143. static PyObject *
  144. termios_tcsendbreak(self, args)
  145.     PyObject *self;
  146.     PyObject *args;
  147. {
  148.     int fd, duration;
  149.  
  150.     if (!PyArg_Parse(args, "(ii)", &fd, &duration))
  151.         return NULL;
  152.     if (tcsendbreak(fd, duration) == -1)
  153.         PyErr_SetFromErrno(TermiosError);
  154.  
  155.     Py_INCREF(Py_None);
  156.     return Py_None;
  157. }
  158.  
  159. /* tcdrain(fd) 
  160.    Wait until all queued output to the terminal has been 
  161.    transmitted.  */
  162.  
  163. static PyObject *
  164. termios_tcdrain(self, args)
  165.     PyObject *self;
  166.     PyObject *args;
  167. {
  168.     int fd;
  169.  
  170.     if (!PyArg_Parse(args, "i", &fd))
  171.         return NULL;
  172.     if (tcdrain(fd) == -1)
  173.         PyErr_SetFromErrno(TermiosError);
  174.  
  175.     Py_INCREF(Py_None);
  176.     return Py_None;
  177. }
  178.  
  179. /* tcflush(fd, queue) 
  180.    Clear the input and/or output queues associated with 
  181.    the terminal.  */
  182.  
  183. static PyObject *
  184. termios_tcflush(self, args)
  185.     PyObject *self;
  186.     PyObject *args;
  187. {
  188.     int fd, queue;
  189.  
  190.     if (!PyArg_Parse(args, "(ii)", &fd, &queue))
  191.         return NULL;
  192.     if (tcflush(fd, queue) == -1)
  193.         PyErr_SetFromErrno(TermiosError);
  194.  
  195.     Py_INCREF(Py_None);
  196.     return Py_None;
  197. }
  198.  
  199. /* tcflow(fd, action) 
  200.    Perform operations relating to XON/XOFF flow control on 
  201.    the terminal.  */
  202.  
  203. static PyObject *
  204. termios_tcflow(self, args)
  205.     PyObject *self;
  206.     PyObject *args;
  207. {
  208.     int fd, action;
  209.  
  210.     if (!PyArg_Parse(args, "(ii)", &fd, &action))
  211.         return NULL;
  212.     if (tcflow(fd, action) == -1)
  213.         PyErr_SetFromErrno(TermiosError);
  214.  
  215.     Py_INCREF(Py_None);
  216.     return Py_None;
  217. }
  218.  
  219. static PyMethodDef termios_methods[] =
  220. {
  221.     {"tcgetattr", termios_tcgetattr},
  222.     {"tcsetattr", termios_tcsetattr},
  223.     {"tcsendbreak", termios_tcsendbreak},
  224.     {"tcdrain", termios_tcdrain},
  225.     {"tcflush", termios_tcflush},
  226.     {"tcflow", termios_tcflow},
  227.     {NULL, NULL}
  228. };
  229.  
  230. void
  231. PyInit_termios()
  232. {
  233.     PyObject *m, *d;
  234.  
  235.     m = Py_InitModule("termios", termios_methods);
  236.  
  237.     d = PyModule_GetDict(m);
  238.     TermiosError = Py_BuildValue("s", "termios.error");
  239.     PyDict_SetItemString(d, "error", TermiosError);
  240.  
  241.     if (PyErr_Occurred())
  242.         Py_FatalError("can't initialize module termios");
  243. }
  244.